Handling input maxlength using knockout
I set out to handle maxlength with the following goals:
- Set maxlength on an input field. That took about 10 seconds.
This wasn’t sufficient however. It had two problems:
- This prevents the UI from going over the maxlength, but not code. I preferred a solution that did both.
- Once the maxlength is reached, there is no indication of why the next character typed is ignored. I wanted the textbox to flash red.
So I decided to do the following:
- Have knockout handle the max length and not have maxlength in the html.
- Have knockout change the css style for 3 seconds.
Knockout allows for something called extenders. I quickly saw extenders as the way to solve my problem. I followed the documentation and modified the example for my needs. I used Plunker to develop this solution and have a working model here:
http://plnkr.co/edit/9SZzcIPUSwWjBttHDQ64
My extender is as follows:
ko.extenders.maxLength = function (target, maxLength) { var result = ko.computed({ read: target, write: function (val) { if (maxLength > 0) { if (val.length > maxLength) { var limitedVal = val.substring(0, maxLength); if (target() === limitedVal) { target.notifySubscribers(); } else { target(limitedVal); } result.css("errorborder"); setTimeout(function () { result.css(""); }, 500); } else { target(val); } } else { target(val); } } }).extend({ notify: 'always' }); result.css = ko.observable(); result(target()); return result; };
Now, as you see, I set the css to errorborder, then I remove it 500 milliseconds (1/2 second) later. In order to make this work, I need an errorborder css style. Here is my first quick stab at that.
.errorborder { outline: none; border: 2px solid red; } .errorborder:focus { outline: none; border: 2px solid red; border-color: red; box-shadow: 0 0 3px red; }
The user will see the border of the text box go red for half a second as they try to type more. Having validation text pop-up saying that maxlength has been reached can be done with this as well, but is probably not necessary. This red border should be sufficient visual feedback.